<h1>beego 模板语法指南</h1>

<p>本文讲述 beego 中使用的模板语法，与 go 模板语法基本相同。</p>

<h2>基本语法</h2>

<p>go 统一使用了 <code>{ {</code> 和 <code>} }</code> 作为左右标签，没有其他的标签符号。如果您想要修改为其它符号，可以参考 <a href="http://beego.me/docs/mvc/view/view.md#%E6%A8%A1%E6%9D%BF%E6%A0%87%E7%AD%BE">模板标签</a>。</p>

<p>使用 <code>.</code> 来访问当前位置的上下文</p>

<p>使用 <code>$</code> 来引用当前模板根级的上下文</p>

<p>使用 <code>$var</code> 来访问创建的变量</p>

<p>[more]</p>

<p><strong>模板中支持的 go 语言符号</strong></p>

<pre><code>{ {&quot;string&quot;} } // 一般 string
        { {`raw string`} } // 原始 string
        { {'c'} } // byte
        { {print nil} } // nil 也被支持
</code></pre>

<p><strong>模板中的 pipeline</strong></p>

<p>可以是上下文的变量输出，也可以是函数通过管道传递的返回值</p>

<pre><code>{ {. | FuncA | FuncB | FuncC} }
</code></pre>

<p>当 pipeline 的值等于:</p>

<ul>
    <li>false 或 0<br /></li>
    <li>nil 的指针或 interface<br /></li>
    <li>长度为 0 的 array, slice, map, string<br /></li>
</ul>

<p>那么这个 pipeline 被认为是空</p>

<h4>if &hellip; else &hellip; end</h4>

<pre><code>{ {if pipeline} }{ {end} }
</code></pre>

<p>if 判断时，pipeline 为空时，相当于判断为 False</p>

<pre><code>this.Data[&quot;IsLogin&quot;] = true
this.Data[&quot;IsHome&quot;] = true
this.Data[&quot;IsAbout&quot;] = true
</code></pre>

<p>支持嵌套的循环</p>

<pre><code>{ {if .IsHome} }
{ {else} }
    { {if .IsAbout} }{ {end} }
{ {end} }
</code></pre>

<p>也可以使用 else if 进行</p>

<pre><code>{ {if .IsHome} }
{ {else if .IsAbout} }
{ {else} }
{ {end} }
</code></pre>

<h4>range &hellip; end</h4>

<pre><code>{ {range pipeline} }{ {.} }{ {end} }
</code></pre>

<p>pipeline 支持的类型为 array, slice, map, channel</p>

<p>range 循环内部的 <code>.</code> 改变为以上类型的子元素</p>

<p>对应的值长度为 0 时，range 不会执行，<code>.</code> 不会改变</p>

<pre><code>pages := []struct {
    Num int
}{ {10}, {20}, {30} }

this.Data[&quot;Total&quot;] = 100
this.Data[&quot;Pages&quot;] = pages
</code></pre>

<p>使用 <code>.Num</code> 输出子元素的 Num 属性，使用 <code>$.</code> 引用模板中的根级上下文</p>

<pre><code>{ {range .Pages} }
    { {.Num} } of { {$.Total} }
{ {end} }
</code></pre>

<p>使用创建的变量，在这里和 go 中的 range 用法是相同的。</p>

<pre><code>{ {range $index, $elem := .Pages} }
    { {$index} } - { {$elem.Num} } - { {.Num} } of { {$.Total} }
{ {end} }
</code></pre>

<p>range 也支持 else</p>

<pre><code>{ {range .Pages} }
{ {else} }
    { {/* 当 .Pages 为空 或者 长度为 0 时会执行这里 */} }
{ {end} }
</code></pre>

<h4>with &hellip; end</h4>

<pre><code>{ {with pipeline} }{ {end} }
</code></pre>

<p>with 用于重定向 pipeline</p>

<pre><code>{ {with .Field.NestField.SubField} }
    { {.Var} }
{ {end} }
</code></pre>

<p>也可以对变量赋值操作</p>

<pre><code>{ {with $value := &quot;My name is %s&quot;} }
    { {printf . &quot;slene&quot;} }
{ {end} }
</code></pre>

<p>with 也支持 else</p>

<pre><code>{ {with pipeline} }
{ {else} }
    { {/* 当 pipeline 为空时会执行这里 */} }
{ {end} }
</code></pre>

<h4>define</h4>

<p>define 可以用来定义自模板，可用于模块定义和模板嵌套</p>

<pre><code>{ {define &quot;loop&quot;} }
    &lt;li&gt;{ {.Name} }&lt;/li&gt;
{ {end} }
</code></pre>

<p>使用 template 调用模板</p>

<pre><code>&lt;ul&gt;
    { {range .Items} }
        { {template &quot;loop&quot; .} }
    { {end} }
&lt;/ul&gt;
</code></pre>

<h4>template</h4>

<pre><code>{ {template &quot;模板名&quot; pipeline} }
</code></pre>

<p>将对应的上下文 pipeline 传给模板，才可以在模板中调用</p>

<p><strong>Beego 中支持直接载入文件模板</strong></p>

<pre><code>{ {template &quot;path/to/head.html&quot; .} }
</code></pre>

<p>Beego 会依据你设置的模板路径读取 head.html</p>

<p>在模板中可以接着载入其他模板，对于模板的分模块处理很有用处</p>

<h4>注释</h4>

<p>允许多行文本注释，不允许嵌套</p>

<pre><code>{ {/* comment content
support new line */} }
</code></pre>

<h2>基本函数</h2>

<p>变量可以使用符号 <code>|</code> 在函数间传递</p>

<pre><code>{ {.Con | markdown | addlinks} }
</code></pre>

<pre><code>{ {.Name | printf &quot;%s&quot;} }
</code></pre>

<p>使用括号</p>

<pre><code>{ {printf &quot;nums is %s %d&quot; (printf &quot;%d %d&quot; 1 2) 3} }
</code></pre>

<h4>and</h4>

<pre><code>{ {and .X .Y .Z} }
</code></pre>

<p>and 会逐一判断每个参数，将返回第一个为空的参数，否则就返回最后一个非空参数</p>

<h4>call</h4>

<pre><code>{ {call .Field.Func .Arg1 .Arg2} }
</code></pre>

<p>call 可以调用函数，并传入参数</p>

<p>调用的函数需要返回 1 个值 或者 2 个值，返回两个值时，第二个值用于返回 error 类型的错误。返回的错误不等于 nil 时，执行将终止。</p>

<h4>index</h4>

<p>index 支持 map, slice, array, string，读取指定类型对应下标的值</p>

<pre><code>this.Data[&quot;Maps&quot;] = map[string]string{&quot;name&quot;: &quot;Beego&quot;}
</code></pre>

<pre><code>{ {index .Maps &quot;name&quot;} }
</code></pre>

<h4>len</h4>

<pre><code>{ {printf &quot;The content length is %d&quot; (.Content|len)} }
</code></pre>

<p>返回对应类型的长度，支持类型：map, slice, array, string, chan</p>

<h4>not</h4>

<p>not 返回输入参数的否定值，if true then false else true</p>

<h4>or</h4>

<pre><code>{ {or .X .Y .Z} }
</code></pre>

<p>or 会逐一判断每个参数，将返回第一个非空的参数，否则就返回最后一个参数</p>

<h4>print</h4>

<p>对应 fmt.Sprint</p>

<h4>printf</h4>

<p>对应 fmt.Sprintf</p>

<h4>println</h4>

<p>对应 fmt.Sprintln</p>

<h4>urlquery</h4>

<pre><code>{ {urlquery &quot;http://beego.me&quot;} }
</code></pre>

<p>将返回</p>

<pre><code>http%3A%2F%2Fbeego.me
</code></pre>

<h4>eq / ne / lt / le / gt / ge</h4>

<p>这类函数一般配合在 if 中使用</p>

<p><code>eq</code>: arg1 == arg2<br />
    <code>ne</code>: arg1 != arg2<br />
    <code>lt</code>: arg1 &lt; arg2<br />
    <code>le</code>: arg1 &lt;= arg2<br />
    <code>gt</code>: arg1 &gt; arg2<br />
    <code>ge</code>: arg1 &gt;= arg2</p>

<p>eq 和其他函数不一样的地方是，支持多个参数，和下面的逻辑判断相同</p>

<pre><code>arg1==arg2 || arg1==arg3 || arg1==arg4 ...
</code></pre>

<p>与 if 一起使用</p>

<pre><code>{ {if eq true .Var1 .Var2 .Var3} }{ {end} }
</code></pre>

<pre><code>{ {if lt 100 200} }{ {end} }
</code></pre>

<blockquote>
    <p>更多文档请访问 <a href="http://beego.me/docs/mvc/view/view.md">beego 官网</a>。</p>
</blockquote>
